#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<errno.h>








int main()
{
   char* const argv[]={(char*)"ls",(char*)"-a",(char*)"-l",NULL};
   execvp("ls",argv);
   
   // execv("/usr/bin/ls",argv);

    return 0;
}
















// 
//extern int putenv(char*string);
//
//int main()
//{
//    //错误做法
//    //const char*MY_ENV[]={"MY_ENV=10",NULL};
//    
//    //正确做法
//    extern char** environ;
//    char MY_ENV[]="MY_ENV=10";
//    putenv((char*)MY_ENV);
//
//    execle("./mycmd","mycmd",NULL,environ);
//    printf("替换失败\n");
//
//    return 0;
//}
//
//




// 
//int main()
//{
//    printf("进程开始\n");
//    execlp("ls","ls","-a","-l",NULL);
//    //execlp("mycmd","mycmd",NULL); //替换失败，因为不是PATH的路径下的程序
//    printf("进程结束\n");//不会执行这一行代码
//
//    return 0;
//}




// 
//
////创建子进程进行程序替换
//int main()
//{
//    pid_t id=fork();
//
//    if(id==0)//子进程
//    {
//        printf("这是子进程\n");
//        execl("./mycmd","mycmd",NULL);//发生写时拷贝
//    }
//    
//    printf("父进程代码还在哦!\n");
//    //回收子进程之后再退出
//    waitpid(id,NULL,0);
//    return 0;
//}





//int main()
//{
//   
//   //int a=10;
//   //printf("%p\n",&a);
//    printf("进程开始\n");
//    
//    //程序替换
//    //       路径    程序  选项
//   // execl("/usr/bin/ls","ls","-a","-l",NULL);
//    //execl("/home/ldh/2024/June/6-4/mycmd","./mycmd", NULL);
//   int ret= execl("./mycmd","mycmd", NULL); //也可以是相对路径，执行我们自己编写的程序，这时候命令行参数的第一个字符串可以不带 ./  
//
//    if(ret==-1) //这个判断只会在替换失败的时候有效，因为如果程序替换成功代码就被覆盖了，执行不到这行代码
//    {
//        perror("execl failed");
//        exit(1);
//    }
//
//
//    printf("进程结束\n");
//
//    return 0;
//}
//




// 
//int main()
//{
//    pid_t id=fork();
//    if(id<0)
//    {
//        perror("fork fail");
//        exit(errno);
//    }
//
//    if(id==0)
//    {
//       // sleep(5);
//       // exit(10);  //子进程正常退出，退出码为10
//        char*p =NULL;
//        *p=10;  //解引用空指针
//    
//    
//    }
//
//    int status =0;
//    waitpid(id,&status,0);
//    
//    if(WIFEXITED(status)) //为真则说明是异常退出
//    {
//        printf("正常退出，退出码为:%d\n",WEXITSTATUS(status));
//    }
//    
//    else
//    {
//        printf("异常终止，信号:%d\n",status&0x7f);
//    }
//    
//    
//    
//    
//    //printf("status:%d\n",status);
//    
//    //先看最低七位是否为0
//    //if(status&0x7f) //最低七位不为 0
//    //{
//    //    printf("异常终止，信号为:%d\n", status&0x7f);
//    //}
//    //else //最低七位为 0 
//    //{
//    //    //退出码为第8-15位
//    //    int exit_code = (status>>8)&0xff;
//    //    printf("正常退出,退出码为 %d\n",exit_code);
//    //}
//    
//
//    return 0;
//}
//




////任务列表我们可以使用全局的函数指针数组来设置

//void task1()
//{
//    printf("任务1\n");
//}
//
//void task2()
//{
//    printf("任务2\n");
//
//}
//
//void task3()
//{
//    printf("任务3\n");
//}
//
//void task4()
//{
//    printf("任务4\n");
//}
//
////全局函数指针数组
//void (*TaskList[10])();
//
//
//
//
//int main()
//{   
//    //装配任务列表
//    TaskList[0]=task1;
//    TaskList[1]=task2;
//    TaskList[2]=task3;
//    TaskList[3]=task3;
//    TaskList[4]=NULL;//用来当作循环退出条件
//    pid_t id=fork();
//    if(id<0)
//    {
//        perror("fork failed");
//        exit(errno);
//    }
//    
//    
//    if(id==0)
//    {
//        //子进程执行 10 秒
//        int cnt=10;
//        while(cnt)
//        {
//            printf("%d\n",cnt--);
//            sleep(1);
//        }
//        exit(0);
//    }
//    //父进程
//    int status=0;
//    while(1)
//    { 
//        int ret=waitpid(id,&status,WNOHANG);
//        if(ret<0)
//        {
//            perror("wairpid failed ");
//            exit(errno);
//        }
//        else if(ret==0) //子进程没有退出
//        {
//            printf("子进程还没退出\n");
//            //干点其他事
//            //可以去执行一个任务列表
//            for(int i=0;TaskList[i];++i)
//            {
//                TaskList[i]();
//            }
//
//
//            //休眠2秒之后再次等待
//            sleep(2);
//        }
//        else //等待成功
//        {
//            break;
//        }
//    }
//
//    printf("status: %d\n",status);
//
//    return 0;
//}
//
//








//int main()
//{
//    pid_t id=fork();
//    if(id<0)
//    {
//        perror("fork fail");
//        exit(errno);
//    }
//
//    if(id==0)//子进程
//    {
//        int cnt=5;
//        while(cnt)
//        {
//            printf("子进程: %d\n",cnt--);
//            sleep(1);
//        }
//        exit(0);
//    }
//    
//    //父进程
//    sleep(10);
//    int status=0;
//    //wait(&status);
//    waitpid(id,&status,0);
//    printf("退出结果 :%d\n",status);
//    //睡眠10秒再退出，便于观察
//    sleep(10);
//
//
//    return 0;
//}

